<html>
<head>
<title>Listr - a Flickr tool by cmepw.org</title>
	<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
	<!--<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>-->

	<script type="text/javascript" src="jQueryUI/jquery-ui-1.8.2.custom.min.js"></script>
	<!--<script type="text/javascript" src="jQueryUI/jquery-ui-1.8.2.custom.js"></script>-->
	<link rel="stylesheet" type="text/css" href="jQueryUI/jquery-ui-1.8.2.custom.css" />

	<script type="text/javascript" src="ext/tablesorter/jquery.tablesorter.js"></script>
	<link rel="stylesheet" type="text/css" href="ext/tablesorter/style.css" />

	<script type="text/javascript" src="ext/jquery.cookies.2.2.0.js"></script>

	<script type="text/javascript" src="js/jQueryUtil.js"></script>

	<script type="text/javascript" src="js/Flickr.js"></script>
	<script type="text/javascript" src="js/FlickrPhotoset.js"></script>
	<script type="text/javascript" src="js/FlickrSearch.js"></script>

	<script type="text/javascript">
// fixme: move this into another script file
function setCookieOptions()
{
	var monthFromToday = new Date();
	monthFromToday.setDate(monthFromToday.getDate() + 30);
	$.cookies.setOptions({
		domain: ".cmepw.org",
		path: "/",
		expiresAt: monthFromToday
	});
}


// fixme: move this into another script file
function getParameterByName(name)
{
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+name+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec( window.location.href );
	if (results == null)
		return "";
	else
		return results[1];
}
	</script>

	<script type="text/javascript">
setCookieOptions(); // fixme: would be nice to set a cookie path here
var flickr = Flickr("Listr");


$(function()
{
	var authButton = $("#authButton");
	authButton[0].disabled = true;
	authButton.click(function() { window.location = "auth.php"; });

	var datePickerOptions = { dateFormat: 'yy-mm-dd' };
	$("#fromDateInput").datepicker(datePickerOptions);
	$("#toDateInput").datepicker(datePickerOptions);

	$("#dateDiv input:text").change(function() { $("#dateRadio")[0].checked = true; });
	$("#setSelect").change(function() { $("#setRadio")[0].checked = true; });
	$("#tagsDiv input").change(function() { $("#tagsRadio")[0].checked = true; });
	$("#paramsForm").submit(function() { onParamsFormSubmit(); return false; });

	$("#photosTable").tablesorter({
		headers: {
			0: { sorter: false },
			1: { sorter: false },
			2: { sorter: false }
		}});
	$("#photosTable").bind("sortStart",
		function() {
			$("#photosTable tr.min").removeClass("min");
			$("#photosTable tr.max").removeClass("max");
			updateCounts(-1, -1);
		});

	flickr.checkAuth(authCallback);
});


function authCallback(isAuthorized)
{
	$("#authMsg").html(isAuthorized
		? flickr.getUserName() + " is authorized"
		: "Not authorized");
	$("#authButton")[0].disabled = isAuthorized;
	if (isAuthorized)
		loadSets();
}


function loadSets()
{
	$("#setMsg").html("Loading sets...");
	flickr.getSets(setsCallback);
}


function setsCallback(setMap)
{
	$("#setMsg").html("");
	var setSelect = $("#setSelect")[0];
	for (setName in setMap) {
		var newOption = document.createElement("option");
		newOption.text = setName;
		newOption.value = setMap[setName];
		setSelect.add(newOption);
	}
}


var search = null;
function onParamsFormSubmit()
{
	$("#paramsForm span").html("");

	var selectedRadio = $("#paramsForm input:radio:checked");
	if (selectedRadio.length == 0) {
		$("#submitMsg").html("Specify search type");
		return;
	}

	$("#photosTable tbody").html("");
	$("#photosTable tfoot tr th:nth-child(3)").html(0);
	$("#photosTable").trigger("update");

	// fixme: can this be done with '== $("#setRadio")' or something?
	if (selectedRadio.val() == "Date") {
		var fromDate = $("#fromDateInput").datepicker("getDate");
		var toDate = $("#toDateInput").datepicker("getDate");
		if (fromDate == null || toDate == null || fromDate > toDate) {
			$("#dateMsg").html("Specify valid dates");
			return;
		}
		toDate.setHours(23, 59, 59, 999);
		$("#paramsForm input:submit").val("Listing...")[0].disabled = true;
		previousSearchLength = 0;
		search = flickr.getSearch();
		search.setTakenDateRange(fromDate.toISOString(), toDate.toISOString());
		search.startSearch(searchCallback, doneCallback);
	}
	else if (selectedRadio.val() == "Set") {
		var selectedSetId = $("#setSelect").val();
		if (selectedSetId == null || selectedSetId == "") {
			$("#setMsg").html("Specify valid set");
			return;
		}
		$("#paramsForm input:submit").val("Listing...")[0].disabled = true;
		previousSetLength = 0;
		set = flickr.selectSet(selectedSetId, setSelectCallback, doneCallback);
	}
	else if (selectedRadio.val() == "Tags") {
		var specifiedTags = $.trim($("#tagsInput").val());
		if (specifiedTags == "") {
			$("#tagsMsg").html("Specify non-empty tags");
			return;
		}
		$("#paramsForm input:submit").val("Listing...")[0].disabled = true;
		previousSearchLength = 0;
		search = flickr.getSearch();
		search.setTags(specifiedTags, $("#requireAllTagsCheck").is(":checked"));
		search.startSearch(searchCallback, doneCallback);
	}
	// else ???
}


// fixme: make this generic
function doneCallback()
{
	$("#paramsForm input:submit").val("List")[0].disabled = false;
	$("#photosTable").trigger("sorton", [[[3,0]]]); 
}


var previousSearchLength = 0; // fixme: breaks if second set is requested before first finishes
function searchCallback()
{
	var photos = search.getPhotos();
	photosSelectCallback(photos, previousSearchLength);
	previousSearchLength = photos.length;
}


var set = null;
var previousSetLength = 0; // fixme: breaks if second set is requested before first finishes
function setSelectCallback()
{
	photosSelectCallback(set.photos, previousSetLength);
	previousSetLength = set.photos.length;
}


// items from firstNewIndex to photosArray.length - 1 are new
function photosSelectCallback(photosArray, firstNewIndex)
{
	var newRows = "";
	for (var i = firstNewIndex; i < photosArray.length; ++i)
		newRows += appendPhoto(photosArray[i]);
	$("#photosTable tbody").append(newRows);
	$("#photosTable tfoot tr th:nth-child(3)").html($("#photosTable tbody tr").length);
	$("#photosTable").trigger("update");
}


function getPhotosUrl()
	{ return "http://flickr.com/photos/" + flickr.getUserName() + "/"}


function getPhotoUrl(photoId)
	{ return getPhotosUrl() + photoId + "/"; }


function getArchiveUrl(archiveType, date)
	{ return getPhotosUrl() + "archives/date-" + archiveType + "/" + $.datepicker.formatDate("yy/mm/dd/", date); }


// fixme: rename this function
function appendPhoto(photo)
{
	var takenDate = new Date(photo.datetaken);
	var postedDate = new Date(parseInt(photo.dateupload) * 1000);
	return "<tr>"
		+ "<td onclick='setMin(this);'>Min</td>"
		+ "<td onclick='setMax(this);'>Max</td>"
		+ "<td> </td>"
		+ "<td><a href='" + getPhotoUrl(photo.id) + "'>" + photo.title + "</a></td>"
		+ "<td><a href='" + getArchiveUrl("taken", takenDate) + "'>" + photo.datetaken + "</a></td>" // 2010-02-05 15:41:33
		+ "<td><a href='" + getArchiveUrl("posted", postedDate) + "'>"
			+ $.datepicker.formatDate("yy-mm-dd", postedDate) + " " + postedDate.toLocaleTimeString() + "</td>"
		+ "<td>" + photo.o_width + "</td>"
		+ "<td>" + photo.o_height + "</td>"
		+ "</tr>";
}


function setMin(tdElement)
{
	$("#photosTable tr.min").removeClass("min");

	var minRow = $(tdElement).parent();
	minRow.addClass("min");

	var maxRow = $("#photosTable tr.max");
	if (maxRow.length == 1)
		updateCounts(minRow.index(), maxRow.index());
}


function setMax(tdElement)
{
	$("#photosTable tr.max").removeClass("max");

	var maxRow = $(tdElement).parent();
	maxRow.addClass("max");

	var minRow = $("#photosTable tr.min");
	if (minRow.length == 1)
		updateCounts(minRow.index(), maxRow.index());
}


function updateCounts(minIndex, maxIndex)
{
	var rows = $("#photosTable tbody tr");
	rows.removeClass("counted").children("td:nth-child(3)").html(""); // nth-child counting starts at 1

	if (minIndex >= 0 && maxIndex >= minIndex)
		for (var i = minIndex; i <= maxIndex; ++i) {
			var html = i - minIndex + 1;
			if (i == minIndex || i == maxIndex)
				html += " <a href='javascript:downloadImageList(" + minIndex + "," + maxIndex + ");'>Save</a>";
			rows.eq(i).addClass("counted").children("td:nth-child(3)").html(html);
		}
}


function downloadImageList(minIndex, maxIndex)
{
	//var onlyNames = confirm("This will download only the image names.  Press 'Cancel' below to download dates as well.");
	if (minIndex != null && maxIndex != null && (minIndex < 0 || minIndex > maxIndex)) {
		alert("Invalid range set.  Could not download image list.");
		return;
	}

	var rows = $("#photosTable tbody tr");
	if (minIndex != null && maxIndex != null)
		rows = rows.slice(minIndex, maxIndex + 1); // need "+ 1" here because these params work like C++ iterators

	var imageNames = "";
	rows.each(function() { imageNames += $(this).children("td:nth-child(4)").text() + "\n"; });

	// fixme: MODIFIED FROM STACKOVERFLOW, REWRITE USING JQUERY
	var form = document.createElement("form");
	form.setAttribute("method", "post");
	form.setAttribute("action", "/php/DownloadAsAttachment.php");
	
	//var fileNameField = document.createElement("input");
	//fileNameField.setAttribute("type", "hidden");
	//fileNameField.setAttribute("name", "fileName");
	//fileNameField.setAttribute("value", "images.txt");
	//form.appendChild(fileNameField);

	var contentField = document.createElement("input");
	contentField.setAttribute("type", "hidden");
	contentField.setAttribute("name", "content");
	contentField.setAttribute("value", imageNames);
	form.appendChild(contentField);

	form.submit();
}


function countRows(tdElement)
{
	var checkedBoxen = $("input:checkbox:checked");
	if (checkedBoxen.length != 2)
		return;
	var checkedRows = checkedBoxen.parents("tr");
	var higherRow = checkedRows.eq(1).index();
	var lowerRow = checkedRows.eq(0).index();
	alert(Math.abs(higherRow - lowerRow) + 1);
}
	</script>

	<style>
body {
	font-family: sans-serif;
}

#photosTable tr.min td, #photosTable tr.max td, #photosTable tr.counted td {
	background: #ddf;
}

tr.min td:nth-child(1), tr.max td:nth-child(2) {
	font-weight: bold;
}

.ui-datepicker {
	font-size: 75%;
}
		
.error {
	color: #ff0000;
}
	</style>

<script type="text/javascript">
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-4469627-1']);
	_gaq.push(['_trackPageview']);

	(function() {
		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	})();
</script>

</head>
<body>
	<h1>Step 1: Authenticate with Flickr</h1>
	<p id="authMsg">Checking authorization...</p>
	<button id="authButton">Authorize</button>
<hr>
	<h1>Step 2: Search Your Photos</h1>
	<form id="paramsForm">
		<div id="dateDiv">
			<input type="radio" name="searchType" value="Date" id="dateRadio"/>
			<label for="dateRadio">Date</label>
			<label for="fromDateInput">From</label>
			<input id="fromDateInput" size="10"/>
			<label for="toDateInput">To</label>
			<input id="toDateInput" size="10"/>
			<span id="dateMsg" class="error"></span>
		</div>

		<div id="setDiv">
			<input type="radio" name="searchType" value="Set" id="setRadio"/>
			<label for="setRadio">Set</label>
			<select id="setSelect"></select>
			<span id="setMsg" class="error"></span>
		</div>

		<div id="tagsDiv">
			<input type="radio" name="searchType" value="Tags" id="tagsRadio"/>
			<label for="tagsRadio">Tags</label>
			<input id="tagsInput" size="40"/>
			<input type="checkbox" id="requireAllTagsCheck"/>
			<label for="requireAllTagsCheck">Require All</label>
			<span id="tagsMsg" class="error"></span>
		</div>
		
		<div>
			<input type="submit" value="List"/>
			<span id="submitMsg" class="error"></span>
		</div>
	</form>
<hr>
	<h1>Step 3: Sort, Set Ranges, Count, Export... Enjoy!</h1>
	<table id="photosTable" class="tablesorter" cellspacing="1">
		<thead>
			<tr>
				<th>Min</th>
				<th>Max</th>
				<th>Count <a href="javascript:downloadImageList();">Save All</a></th>
				<th>Title</th>
				<th>Date Taken</th>
				<th>Date Posted</th>
				<th>Width</th>
				<th>Height</th>
			</tr>
		<thead>
		<tbody>
		</tbody>
		<tfoot>
			<tr>
				<th></th>
				<th></th>
				<th>0</th>
				<th></th>
				<th></th>
				<th></th>
				<th></th>
				<th></th>
			</tr>
		</tfoot>
	</table>
</body>






